import { customFiltersSchema } from '/@/renderer/features/shared/utils';

/**
 * Parse a string array from URLSearchParams
 * Returns undefined if the key doesn't exist or array is empty
 */
export const parseArrayParam = (
    searchParams: URLSearchParams,
    key: string,
): string[] | undefined => {
    const values = searchParams.getAll(key);
    return values.length > 0 ? values : undefined;
};

/**
 * Parse a boolean from URLSearchParams
 * Returns undefined if the key doesn't exist
 */
export const parseBooleanParam = (
    searchParams: URLSearchParams,
    key: string,
): boolean | undefined => {
    const value = searchParams.get(key);
    if (value === null) return undefined;
    return value === 'true';
};

/**
 * Parse an integer from URLSearchParams
 * Returns undefined if the key doesn't exist or value is invalid
 */
export const parseIntParam = (searchParams: URLSearchParams, key: string): number | undefined => {
    const value = searchParams.get(key);
    if (value === null) return undefined;
    const parsed = parseInt(value, 10);
    return isNaN(parsed) ? undefined : parsed;
};

/**
 * Parse a string from URLSearchParams
 * Returns undefined if the key doesn't exist
 */
export const parseStringParam = (
    searchParams: URLSearchParams,
    key: string,
): string | undefined => {
    const value = searchParams.get(key);
    return value === null ? undefined : value;
};

/**
 * Parse JSON from URLSearchParams
 * Returns undefined if the key doesn't exist or parsing fails
 */
export const parseJsonParam = <T = unknown>(
    searchParams: URLSearchParams,
    key: string,
): T | undefined => {
    const value = searchParams.get(key);
    if (value === null) return undefined;
    try {
        const parsed = JSON.parse(value);
        // Validate against schema if provided
        return parsed;
    } catch {
        return undefined;
    }
};

/**
 * Set or remove a value in URLSearchParams
 * If value is null or undefined, removes the key
 */
export const setSearchParam = (
    searchParams: URLSearchParams,
    key: string,
    value: boolean | null | number | Record<string, any> | string | string[] | undefined,
): URLSearchParams => {
    const newParams = new URLSearchParams(searchParams);

    if (value === null || value === undefined) {
        newParams.delete(key);
        return newParams;
    }

    if (Array.isArray(value)) {
        newParams.delete(key);
        value.forEach((v) => newParams.append(key, String(v)));
        return newParams;
    }

    if (typeof value === 'boolean') {
        newParams.set(key, String(value));
        return newParams;
    }

    if (typeof value === 'number') {
        newParams.set(key, String(value));
        return newParams;
    }

    newParams.set(key, value as string);
    return newParams;
};

/**
 * Set or remove a JSON value in URLSearchParams
 * If value is null or undefined, removes the key
 */
export const setJsonSearchParam = (
    searchParams: URLSearchParams,
    key: string,
    value: null | Record<string, any> | undefined,
): URLSearchParams => {
    const newParams = new URLSearchParams(searchParams);

    if (value === null || value === undefined) {
        newParams.delete(key);
        return newParams;
    }

    newParams.set(key, JSON.stringify(value));
    return newParams;
};

/**
 * Parse custom filters from URLSearchParams with validation
 */
export const parseCustomFiltersParam = (
    searchParams: URLSearchParams,
    key: string,
): Record<string, any> | undefined => {
    const value = parseJsonParam(searchParams, key);
    if (value === undefined) return undefined;

    try {
        return customFiltersSchema.parse(value);
    } catch {
        return undefined;
    }
};
